package bdz.projects.atwww.electrolux.controls
{
	import bdz.projects.atwww.electrolux.events.ELEvent;
	import bdz.projects.atwww.electrolux.events.ELUIEvent;
	import bdz.projects.atwww.electrolux.model.ELModel;
	import bdz.projects.atwww.electrolux.model.core.ELOption;
	import bdz.projects.atwww.electrolux.model.core.ELProgram;
	import bdz.projects.atwww.electrolux.ui.ELOptionsControl;
	import bdz.projects.atwww.electrolux.ui.ELPlayPauseControl;
	import bdz.projects.atwww.electrolux.ui.ELProgressControl;
	import bdz.projects.atwww.electrolux.ui.ELRotaryControl;
	
	import flash.events.EventDispatcher;
	import flash.events.MouseEvent;

	public class ELUIController extends EventDispatcher {
		
		private var _rotaryControl:ELRotaryControl;
		private var _optionControl:ELOptionsControl;
		private var _playPauseControl:ELPlayPauseControl;
		private var _progressControl:ELProgressControl;
		private var _programRunner:ELProgramRunner;
		
		private var _model:ELModel = ELModel.getInstance();
		private var _isPlaying:Boolean = false;
		
		public var analogue:Boolean = false;
		private var _timePassed:Number = 0;
		private var _cachedTime:Number = 0;
		private var _runned:Boolean = false;
		private var tmanaged:Boolean = false;
		
		public function ELUIController() {
			_programRunner = new ELProgramRunner();
			_programRunner.addEventListener(ELEvent.PROGRAM_PROGRESS, onProgramRunProgress);
			_programRunner.addEventListener(ELEvent.PROGRAM_COMPLETE, onProgramRunComplete);
			
			_model.addEventListener(ELEvent.PROGRAM_SELECTED, onProgramSet);
			super();
		}
		
		private function enableUIS(b:Boolean):void{
			_optionControl.enabled = b;
			_rotaryControl.enabled = b;
		}
		private function onProgramRunProgress(evt:ELEvent):void{
			_timePassed = evt.data+_cachedTime;
			
			_progressControl.time = _programRunner.duration-evt.data;
			
		}
		private function onProgramRunComplete(evt:ELEvent):void{
			_progressControl.time = 0;
			enableUIS(true);
		}
		private function onProgramSet(evt:ELEvent):void{
			try{
				_optionControl.applyOptions(_model.activeProgram);
			}catch(e:Error){}
		}
		private function onPlayPauseAction(evt:MouseEvent):void{
			_model.activeProgram.play();
			
			if(!_isPlaying){
				_runned = true;
				_programRunner.start();
				_playPauseControl.setToPlay();
				dispatchEvent(new ELEvent(ELEvent.PROGRAM_STARTED));
			}else{
				_programRunner.pause();
				_cachedTime = _timePassed;
				_playPauseControl.setToStop();
				dispatchEvent(new ELEvent(ELEvent.PROGRAM_PAUSED));
			}
			_isPlaying = !_isPlaying;
			enableUIS(!_isPlaying);
			
		}
		private function activateProgram(p:ELProgram):void{
			p.revertToOriginalBase();
			_timePassed = _cachedTime = 0;
			_programRunner.analogue = analogue;
			_runned = false;
			_programRunner.reset();
			_model.activateProgram(p);
			
		}
		private function onActivateProgram(evt:ELUIEvent):void{
			activateProgram(evt.data as ELProgram);
			setNewTime();
		}
		private function setNewTime(ubase:Boolean = false):void{
			if(ubase){
				_programRunner.duration = _progressControl.time = _model.activeProgram.cachedTime - _cachedTime;
			}else{
				_programRunner.duration = _progressControl.time = _model.activeProgram.totalTime - _cachedTime;
			}
			if(analogue){
				if(_programRunner.duration >= 100){
					_programRunner.duration = _progressControl.time  = 99;
				}
			}
			
		}
		private function onOptionChanged(evt:ELUIEvent):void{
			var eo:ELOption;			
			if(evt.data.alias.toLowerCase() == "delay"){
				eo = evt.data as ELOption;	
				_model.activeProgram.appendToBaseTime(eo.selected.time);
			}else if(evt.data.alias.toLowerCase() == "time manager"){
				eo = evt.data as ELOption;
				if(Number(eo.selected.value)){
					_programRunner.duration = _progressControl.time = _model.activeProgram.customTime = Number(eo.selected.value);
					return;
				}else{
					_model.activeProgram.timeManaged = false;
					setNewTime(true);
					return;
				}
				
			}
			setNewTime();
		}
		
		public function registerRotaryControl(rc:ELRotaryControl):void{
			_rotaryControl = rc;
			_rotaryControl.controller = this;
			_rotaryControl.addEventListener(ELUIEvent.ACTIVATE_PROGRAM, onActivateProgram);
			_rotaryControl.programs = _model.programs;
		}
		public function registerOptionControl(oc:ELOptionsControl):void{
			_optionControl = oc;
			_optionControl.addEventListener(ELUIEvent.OPTION_CHANGED, onOptionChanged);
			_optionControl.controller = this;	
		}
		public function appendToBaseTime(n:Number):void{
			_model.activeProgram.appendToBaseTime(n);
			setNewTime();
		}
		public function registerPlayPauseControl(ppc:ELPlayPauseControl):void{
			_playPauseControl = ppc;
			_playPauseControl.controller = this;
			_playPauseControl.addEventListener(MouseEvent.CLICK, onPlayPauseAction);
		}
		public function registerProgressControl(pc:ELProgressControl):void{
			_progressControl = pc;
			_progressControl.controller = this;
		}
		public function registerProgramRunner(pr:ELProgramRunner):void{
			_programRunner = pr;
		}
		public function replaceProgramWithAlias(alias:String, xm:XML):void{
			_model.programs.replaceProgramWithAlias(xm, alias);
			_rotaryControl.updateReferences();
		}
		public function cloneActiveProgram(al:String):XML{
			return _model.activeProgram.clone(al);
		}
		public function allUIRegistered():Boolean{
			return (_progressControl != null && _playPauseControl != null && _optionControl != null && _rotaryControl != null);
		}
		public function get timeManager():ELOption{
			return _model.activeProgram.timeManager;
		}
		public function get activeProgramTime():Number{
			return _model.activeProgram.totalTime;
		}
		public function get activeProgramOrigTime():Number{
			return _model.activeProgram.origTime;
		}
		
		
	}
}
